package com.yeziji.utils;

import com.yeziji.constant.VariousStrPool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Base64Utils;
import org.springframework.util.StringUtils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * Gzip 压缩解压工具类
 *
 * @author gzkemays
 * @since 2021/12/21 14:32
 */
@Slf4j
public class GzipUtils {
    /**
     * gzip 压缩
     *
     * @param str 源文本
     * @return 压缩数据
     */
    public static byte[] compress(String str) {
        if (!StringUtils.hasText(str)) {
            return new byte[0];
        }
        GZIPOutputStream gzip = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            gzip = new GZIPOutputStream(bos);
            gzip.write(str.getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            log.error("Gzip 压缩文本失败: {}", e.getMessage(), e);
        } finally {
            if (gzip != null) {
                try {
                    gzip.close();
                } catch (IOException e) {
                    log.error("Gzip 压缩文本关闭流失败: {}", e.getMessage(), e);
                }
            }
        }
        return bos.toByteArray();
    }

    /**
     * gzip 解压
     *
     * @param bytes 原压缩字节
     * @return 源文本
     */
    public static String uncompress(byte[] bytes) {
        if (bytes.length == 0) {
            return VariousStrPool.EMPTY;
        }
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            GZIPInputStream gzip = new GZIPInputStream(bais);
            byte[] buffer = new byte[1024];
            int i;
            while ((i = gzip.read(buffer)) != -1) {
                baos.write(buffer, 0, i);
            }
            gzip.close();
        } catch (IOException e) {
            log.error("Gzip 解压文本失败: {}", e.getMessage(), e);
        } finally {
            try {
                bais.close();
                baos.close();
            } catch (IOException e) {
                log.error("Gzip 解压文本关闭流失败: {}", e.getMessage(), e);
            }
        }
        return baos.toString();
    }

    /**
     * 压缩至 base64 文本
     *
     * @param str 原文本
     * @return {@link String} 压缩 base64 文本
     */
    public static String compressToBase64Str(String str) {
        if (!StringUtils.hasText(str)) {
            return "";
        }
        return Base64Utils.encodeToString(compress(str));
    }

    /**
     * 解压 base64 文本
     *
     * @param str 原来压缩的 base64 文本
     * @return {@link String} 解压结果
     */
    public static String uncompressByBase64Str(String str) {
        if (!StringUtils.hasText(str)) {
            return "";
        }
        return uncompress(Base64Utils.decodeFromString(str));
    }

    public static void main(String[] args) {
        String s = compressToBase64Str("你好");
        System.out.println("s = " + s);
        String s1 = uncompressByBase64Str(s);
        System.out.println("s = " + s1);
    }
}
